#####################################################################
#                                                                   #
#  THIS IS A SOURCE CODE FILE FROM A PROGRAM TO INTERACT WITH THE   #
# LBRY PROTOCOL ( lbry.com ). IT WILL USE THE LBRY SDK ( lbrynet )  #
# FROM THEIR REPOSITORY ( https://github.com/lbryio/lbry-sdk )      #
# WHICH I GONNA PRESENT TO YOU AS A BINARY. SINCE I DID NOT DEVELOP #
# IT AND I'M LAZY TO INTEGRATE IN A MORE SMART WAY. THE SOURCE CODE #
# OF THE SDK IS AVAILABLE IN THE REPOSITORY MENTIONED ABOVE.        #
#                                                                   #
#      ALL THE CODE IN THIS REPOSITORY INCLUDING THIS FILE IS       #
# (C) J.Y.Amihud and Other Contributors 2021. EXCEPT THE LBRY SDK.  #
# YOU CAN USE THIS FILE AND ANY OTHER FILE IN THIS REPOSITORY UNDER #
# THE TERMS OF GNU GENERAL PUBLIC LICENSE VERSION 3 OR ANY LATER    #
# VERSION. TO FIND THE FULL TEXT OF THE LICENSE GO TO THE GNU.ORG   #
# WEBSITE AT ( https://www.gnu.org/licenses/gpl-3.0.html ).         #
#                                                                   #
# THE LBRY SDK IS UNFORTUNATELY UNDER THE MIT LICENSE. IF YOU ARE   #
# NOT INTENDING TO USE MY CODE AND JUST THE SDK. YOU CAN FIND IT ON #
# THEIR OFFICIAL REPOSITORY ABOVE. THEIR LICENSE CHOICE DOES NOT    #
# SPREAD ONTO THIS PROJECT. DON'T GET A FALSE ASSUMPTION THAT SINCE #
# THEY USE A PUSH-OVER LICENSE, I GONNA DO THE SAME. I'M NOT.       #
#                                                                   #
# THE LICENSE CHOSEN FOR THIS PROJECT WILL PROTECT THE 4 ESSENTIAL  #
# FREEDOMS OF THE USER FURTHER, BY NOT ALLOWING ANY WHO TO CHANGE   #
# THE LICENSE AT WILL. SO NO PROPRIETARY SOFTWARE DEVELOPER COULD   #
# TAKE THIS CODE AND MAKE THEIR USER-SUBJUGATING SOFTWARE FROM IT.  #
#                                                                   #
#####################################################################

# This file will handle all kinds of settings

import os
import json
from gi.repository import Gtk

def get_settings_folder(flbry="flbry/"):

    try:
        data_dir = os.environ["XDG_DATA_HOME"] + "/" + flbry # Reducted back since it
                                                             # broke too much and made
                                                             # my settings appear in
                                                             # $XDG_DATA_HOME folder
                                                             # inside the repository.
                                                             # WTF !!!
    except:
        data_dir = os.path.expanduser("~/.local/share/"+flbry)

    try:
        os.makedirs(data_dir)
    except:
        pass

    return data_dir

def load():
    with open(get_settings_folder()+'config.json') as json_file: 
            data = json.load(json_file) 
    return data
            
def save(data):
    with open(get_settings_folder()+'config.json', 'w') as fp:
            json.dump(data, fp, sort_keys=True, indent=4)

def make_sure_file_exists():

    # Let's make some defaults

    defaults = {
        "GTK_icon_theme":"System Theme",
        "notifications":True,
        "auth_token": "",
        "autoconnect": False,
        "comment_api": "https://comments.odysee.com/api/v2",
        "lbrynet_binary": "flbry/lbrynet",
        "librarian_instance": "https://librarian.bcow.xyz/",
        "promote_fast_lbry_in_commnets":True

    }

    # Let's write the Default theme.
    try:
        with open(get_settings_folder()+"config.json") as f:
            data = json.load(f)
        for i in defaults:
            if i not in data:
                data[i] = defaults[i]
    except Exception as e:
        data = defaults
        
    with open(get_settings_folder()+'config.json', 'w') as fp:
        json.dump(data, fp, sort_keys=True, indent=4)
    
def dialogue(w, win):

    # This is the settings dialogue

    # Configuring the window
    
    dialogWindow = Gtk.Dialog("Settings",
            buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
                     Gtk.STOCK_OK, Gtk.ResponseType.OK),
        )

    box = dialogWindow.get_content_area()

    #######################################################################
    #                                                                     #
    #                            THEMES SELECTOR                          #
    #                                                                     #
    #######################################################################

    
    themes_setting = Gtk.ComboBoxText()
    #themes_setting.set_relief(Gtk.ReliefStyle.NONE)

    # Themes are laoded from folder in ./icons

    select = 0

    icon_themes = os.listdir(os.getcwd()+"/icons")
    icon_themes.append("System Theme")
    for n, theme in enumerate(icon_themes):
        themes_setting.append_text( theme )
        if win.settings["GTK_icon_theme"] == theme:
            select = n

    
            
    themes_setting.set_active(select)

    theme_box = Gtk.HBox()
    theme_box.pack_start(Gtk.Label("  Icon Theme (requires restart) :  "), False, False, False)
    theme_box.pack_end(themes_setting, False, False, False)
    box.pack_start(theme_box, False, False, 5)

    #######################################################################
    #                                                                     #
    #                            ALL THE REST                             #
    #                                                                     #
    #######################################################################

    # The settings are SHARED WITH FASTLBRY TERMINAL
    # The rest of settings are generated by what's available in the config
    # file. So there could be problems. First we need exclude list.

    exclude = ["GTK_icon_theme", # We have a separate thing for it
               "save_history",   # Used by FastLBRY terminal, not interesting here
               "theme",          # The theme of FastLBRY terminal
               "markdown_reader",# In FastLBRY GTK we have a UI implementation for this
               "graph_force_ASCII", # Another FastLBRY Termianl only function
               "ignore_width_forcing", # FASTLBRY TERMINAL AGAIN
               "channel"         # This one is set in the top pannel of the window
    ]

    parts = {}
    
    for name in win.settings:
        if name in exclude:
            continue

        parts[name] = {}
        parts[name]["box"] = Gtk.HBox()

        # I want to beutify the name for the setting
        pname = name.replace("_", " ")
        pname = "  "+pname[0].upper()+pname[1:].lower()+"  "
        parts[name]["box"].pack_start(Gtk.Label(pname), False, False, False)

        # Then depending on the type of the data itself, we are going to give
        # inputs

        if type(win.settings[name]) == str:
            parts[name]["entry"]  = Gtk.Entry()
            parts[name]["entry"].set_text(win.settings[name])
            parts[name]["entry"].set_size_request(300,40)
            parts[name]["box"].pack_end(parts[name]["entry"], False, False, False)
            
        elif type(win.settings[name]) == bool:
            parts[name]["entry"]  = Gtk.Switch()
            parts[name]["entry"].set_active(win.settings[name])
            parts[name]["box"].pack_end(parts[name]["entry"], False, False, False)

        elif type(win.settings[name]) == float:
            parts[name]["number"] = Gtk.Adjustment(win.settings[name],
                                                   lower=0.0001,
                                                   upper=1000000000,
                                                   step_increment=0.1) 
            parts[name]["entry"]  = Gtk.SpinButton(adjustment=parts[name]["number"],
                                                   digits=4)
            parts[name]["box"].pack_end(parts[name]["entry"], False, False, False)
        elif type(win.settings[name]) == int:
            parts[name]["number"] = Gtk.Adjustment(win.settings[name],
                                                   lower=0,
                                                   upper=1000000000,
                                                   step_increment=4) 
            parts[name]["entry"]  = Gtk.SpinButton(adjustment=parts[name]["number"])
            parts[name]["box"].pack_end(parts[name]["entry"], False, False, False)
        
        box.pack_start(parts[name]["box"], False, False, 5)
    
    # notifications_box = Gtk.HBox()
    # notifications_setting = Gtk.Switch()
    # notifications_setting.set_active(win.settings["notifications"])
    # notifications_box.pack_start(Gtk.Label("  Notifications:  "), False, False, False)
    # notifications_box.pack_end(notifications_setting, False, False, False)
    # box.pack_start(notifications_box, False, False, False)
    



    #######################################################################
    #                                                                     #
    #                      RUNING THE SETTINGS DIALOG                     #
    #                                                                     #
    #######################################################################
    
    # Running the dialog

    box.show_all()
    response = dialogWindow.run()

    if response == Gtk.ResponseType.OK:

        # Here I want to overwrite all the setting to ones
        # chosen by the user.

        win.settings["GTK_icon_theme"] = themes_setting.get_active_text()
        for name in win.settings:
            if name in exclude:
                continue

            value = False
            if type(win.settings[name]) == str:
                value = parts[name]["entry"].get_text()
            elif type(win.settings[name]) == bool:
                value = parts[name]["entry"].get_active()
            elif type(win.settings[name]) == int:
                value = int(parts[name]["entry"].get_value())
            elif type(win.settings[name]) == float:
                value = parts[name]["entry"].get_value()

            win.settings[name] = value
            
        # Then we save everything.
        save(win.settings)
    
    dialogWindow.destroy()
